Understanding Interfaces and Their Implementation in Java
Course: Core Java Training
Topic: Understanding Interfaces and Their Implementation
Course Link: Core Java Training Course
Demo Link: Register for a Free Course Demo
Website: JustAcademy
1. Introduction to Interfaces in Java
An interface in Java is a reference type that defines a contract that implementing classes must follow. It specifies methods that a class agrees to provide, allowing different classes to offer their own implementations of the same behavior.
Interfaces are an important part of Java's object-oriented programming model. They support abstraction, loose coupling, polymorphism, and flexible application design.
For example, a payment application may support credit cards, UPI, and digital wallets. Each payment method works differently, but all can implement a common Payment interface with a pay() method.
interface Payment {
void pay(double amount);
}
Any concrete class implementing this interface must provide an implementation of pay(), unless the class is declared abstract.
2. Learning Objectives
- Understand the meaning and purpose of Java interfaces.
- Learn interface declaration and implementation syntax.
- Understand abstract methods, default methods, and static methods.
- Implement one or multiple interfaces in a class.
- Understand interface inheritance and polymorphism.
- Differentiate interfaces from abstract classes.
- Apply interfaces in practical Java programs.
- Identify common interface implementation errors.
3. What Is an Interface?
An interface defines a set of behaviors that implementing classes are expected to provide. It describes what an object can do without requiring every implementation to use the same internal logic.
For example, a Vehicle interface could define a start() method. A car, motorcycle, and electric scooter could each implement that method differently.
Basic Syntax
interface InterfaceName {
void methodName();
}
The interface keyword declares an interface. The method methodName() is implicitly public and abstract when declared without a body in a traditional interface declaration.
Important Characteristics
- An interface defines a contract for behavior.
- A class uses the
implements keyword to implement an interface.
- A class can implement multiple interfaces.
- An interface cannot be instantiated directly.
- Interface references can refer to objects of implementing classes.
- Interface fields are implicitly
public static final.
- Interfaces can contain abstract methods, default methods, static methods, and private helper methods, depending on the Java version.
4. Declaring an Interface
To declare an interface, use the interface keyword followed by its name and a pair of braces. Inside the interface, declare the methods that implementing classes must support.
interface Animal {
void makeSound();
void eat();
}
In this example, the Animal interface declares two methods: makeSound() and eat(). Neither method has a body, so a concrete implementing class must provide both implementations.
Interface Naming Conventions
- Use meaningful names that describe a capability or role.
- Use PascalCase, such as
Runnable, Printable, or PaymentService.
- Prefer clear behavior-oriented names rather than names tied to implementation details.
5. Implementing an Interface Using the implements Keyword
A class implements an interface by using the implements keyword. The class provides method bodies for the interface's abstract methods.
Example: Implementing an Animal Interface
interface Animal {
void makeSound();
void eat();
}
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
@Override
public void eat() {
System.out.println("Dog eats food");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.makeSound();
dog.eat();
}
}
Output
Dog barks
Dog eats food
Explanation
Animal defines the required behavior.
Dog implements Animal establishes that Dog follows the interface contract.
@Override indicates that the methods implement declarations from the interface.
- The methods are declared
public because interface abstract methods are public, and implementations cannot reduce their visibility.
- The
main() method creates a Dog object and invokes both methods.
6. Why Interface Methods Must Be Implemented
When a concrete class implements an interface, it must implement all inherited abstract methods with compatible signatures and public visibility. If it does not, the compiler reports an error.
An exception is an abstract class: it may implement only some of the methods and leave the remaining abstract methods for a concrete subclass.
interface Printable {
void print();
}
abstract class Document implements Printable {
// The print() method is not implemented here.
}
class Report extends Document {
@Override
public void print() {
System.out.println("Printing report");
}
}
Here, Document is abstract, so it does not need to implement print(). The concrete Report class provides the implementation.
7. Using Interface References
One of the most useful features of interfaces is that an interface reference can point to an object of any class that implements that interface. This helps developers write code that depends on behavior rather than a specific class.
interface Shape {
double calculateArea();
}
class Circle implements Shape {
private double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
class Rectangle implements Shape {
private double length;
private double width;
Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
public double calculateArea() {
return length * width;
}
}
public class Main {
public static void main(String[] args) {
Shape first = new Circle(3);
Shape second = new Rectangle(4, 5);
System.out.printf("Circle area: %.2f%n", first.calculateArea());
System.out.printf("Rectangle area: %.2f%n", second.calculateArea());
}
}
Output
Circle area: 28.27
Rectangle area: 20.00
Both variables are declared as Shape, but the method that runs depends on the actual object. This is an example of runtime polymorphism.
8. Implementing Multiple Interfaces
Java does not allow a class to extend multiple classes, but a class can implement multiple interfaces. This allows a class to combine several independent capabilities.
Example
interface Printable {
void print();
}
interface Scannable {
void scan();
}
class MultiFunctionPrinter implements Printable, Scannable {
@Override
public void print() {
System.out.println("Printing document");
}
@Override
public void scan() {
System.out.println("Scanning document");
}
}
public class Main {
public static void main(String[] args) {
MultiFunctionPrinter printer = new MultiFunctionPrinter();
printer.print();
printer.scan();
}
}
Output
Printing document
Scanning document
The MultiFunctionPrinter class implements both interfaces and must implement both abstract methods. Multiple interfaces are useful when a class needs to support several roles without inheriting implementation from multiple parent classes.
9. Interface Variables and Constants
Variables declared in an interface are implicitly public static final. They are constants shared by all code that accesses the interface.
interface AppConfig {
int MAX_USERS = 100;
String APP_NAME = "Student Portal";
}
public class Main {
public static void main(String[] args) {
System.out.println(AppConfig.MAX_USERS);
System.out.println(AppConfig.APP_NAME);
}
}
Output
100
Student Portal
These declarations are equivalent to public static final constants. They must be initialized when declared and cannot be reassigned.
Best practice: Use interface constants only when they are genuinely part of the interface's shared contract. Avoid placing unrelated application configuration or mutable state in interfaces.
10. Default Methods in Interfaces
Since Java 8, interfaces can contain default methods with method bodies. Default methods allow an interface to provide reusable behavior while maintaining compatibility when new methods are added to existing interfaces.
interface Greeting {
void greet();
default void sayGoodbye() {
System.out.println("Goodbye!");
}
}
class EnglishGreeting implements Greeting {
@Override
public void greet() {
System.out.println("Hello!");
}
}
public class Main {
public static void main(String[] args) {
EnglishGreeting greeting = new EnglishGreeting();
greeting.greet();
greeting.sayGoodbye();
}
}
Output
Hello!
Goodbye!
The class implements the abstract greet() method and inherits the default implementation of sayGoodbye(). It may override the default method if custom behavior is needed.
11. Static Methods in Interfaces
Since Java 8, interfaces can define static methods with bodies. These methods belong to the interface itself and are called using the interface name, rather than through an implementing object.
interface Calculator {
static int add(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
int result = Calculator.add(10, 20);
System.out.println("Sum: " + result);
}
}
Output
Sum: 30
Call the method as Calculator.add(10, 20). An implementing class does not inherit interface static methods as instance methods.
12. Private Methods in Interfaces
Since Java 9, interfaces can contain private methods and private static methods. These methods help share internal logic between default or static methods without exposing that helper behavior as part of the public interface contract.
interface Logger {
default void logInfo(String message) {
printMessage("INFO", message);
}
default void logWarning(String message) {
printMessage("WARNING", message);
}
private void printMessage(String level, String message) {
System.out.println("[" + level + "] " + message);
}
}
public class Main {
public static void main(String[] args) {
Logger logger = new Logger() {};
logger.logInfo("Application started");
logger.logWarning("Low disk space");
}
}
Output
[INFO] Application started
[WARNING] Low disk space
The private helper method is called internally by the default methods. It cannot be called directly by code using the interface reference.
13. Extending Interfaces
An interface can extend another interface using the extends keyword. A child interface inherits the parent interface's method declarations and can introduce additional methods.
interface Animal {
void eat();
}
interface Pet extends Animal {
void play();
}
class Cat implements Pet {
@Override
public void eat() {
System.out.println("Cat eats fish");
}
@Override
public void play() {
System.out.println("Cat plays with a toy");
}
}
public class Main {
public static void main(String[] args) {
Pet pet = new Cat();
pet.eat();
pet.play();
}
}
Output
Cat eats fish
Cat plays with a toy
Because Pet extends Animal, a class implementing Pet must also fulfill the inherited eat() contract.
Multiple Interface Inheritance
An interface can extend more than one interface. For example:
interface Printable {
void print();
}
interface Shareable {
void share();
}
interface DocumentActions extends Printable, Shareable {
void save();
}
A concrete class implementing DocumentActions must implement print(), share(), and save(), unless those methods are already provided by inherited concrete implementations where applicable.
14. Resolving Default Method Conflicts
If a class implements two unrelated interfaces that provide default methods with the same signature, Java requires the class to resolve the conflict by overriding that method. This prevents ambiguity about which default implementation should run.
interface Camera {
default void start() {
System.out.println("Camera started");
}
}
interface MusicPlayer {
default void start() {
System.out.println("Music player started");
}
}
class SmartDevice implements Camera, MusicPlayer {
@Override
public void start() {
System.out.println("Smart device started");
}
}
public class Main {
public static void main(String[] args) {
SmartDevice device = new SmartDevice();
device.start();
}
}
Output
Smart device started
The class provides its own implementation to resolve the conflict. When appropriate, it can explicitly invoke a particular interface's default implementation using syntax such as Camera.super.start().
15. Interfaces and Polymorphism
Polymorphism allows a common interface reference to work with different implementing objects. This makes it possible to replace one implementation with another without changing code that relies only on the interface.
interface Notification {
void send(String message);
}
class EmailNotification implements Notification {
@Override
public void send(String message) {
System.out.println("Email: " + message);
}
}
class SmsNotification implements Notification {
@Override
public void send(String message) {
System.out.println("SMS: " + message);
}
}
public class Main {
static void notifyUser(Notification notification) {
notification.send("Your order has been shipped");
}
public static void main(String[] args) {
notifyUser(new EmailNotification());
notifyUser(new SmsNotification());
}
}
Output
Email: Your order has been shipped
SMS: Your order has been shipped
The notifyUser() method accepts any object implementing Notification. It does not need to know the specific implementation class.
16. Interface vs Abstract Class
| Feature |
Interface |
Abstract Class |
| Declaration |
Uses the interface keyword |
Uses the abstract class keywords |
| Implementation |
A class uses implements |
A class uses extends |
| Multiple inheritance |
A class can implement multiple interfaces |
A class can extend only one class |
| Abstract methods |
Supported |
Supported |
| Instance fields |
Cannot declare ordinary instance fields; fields are constants |
Can declare instance fields |
| Constructors |
Not supported |
Supported |
| Concrete methods |
Default, static, and private methods are supported |
Concrete instance and static methods are supported |
| Best suited for |
Defining a capability or contract |
Sharing state and common implementation among related classes |
When to use an interface: Use an interface when different classes need to support a common behavior, even if they are unrelated in their class hierarchy.
When to use an abstract class: Use an abstract class when related classes should share instance state, constructors, or common implementation.
17. Advantages of Interfaces
- Abstraction: Clients depend on declared behavior rather than implementation details.
- Loose coupling: Implementations can be replaced with fewer changes to calling code.
- Polymorphism: One reference type can represent objects from several implementation classes.
- Multiple capabilities: A class can implement multiple interfaces.
- Testability: Applications can substitute fake or mock implementations during testing.
- Maintainability: Responsibilities can be separated into clearly defined contracts.
- Extensibility: New implementations can be introduced without rewriting code that uses the interface correctly.
18. Limitations and Important Considerations
- An interface cannot be instantiated directly.
- A concrete implementing class must fulfill all inherited abstract method contracts.
- Interfaces cannot have ordinary per-object instance fields or constructors.
- Adding a new abstract method to an existing interface can break source compatibility for concrete implementations that do not implement it.
- Default methods with conflicting signatures may require explicit resolution.
- An interface should represent a coherent contract instead of collecting unrelated methods.
19. Real-World Applications of Interfaces
| Application |
Example Interface |
Possible Implementations |
| Payment processing |
PaymentProcessor |
CardPayment, UpiPayment, WalletPayment |
| Notifications |
NotificationService |
EmailService, SmsService, PushService |
| File handling |
FileExporter |
PdfExporter, CsvExporter |
| Database access |
Repository |
Implementations backed by different data sources |
| Media playback |
Playable |
AudioPlayer, VideoPlayer |
| Background tasks |
Runnable |
Classes that provide a run() implementation |
20. Practical Example: Payment Processing System
This example demonstrates how an interface can create a common contract for different payment methods.
interface PaymentMethod {
boolean processPayment(double amount);
}
class CardPayment implements PaymentMethod {
@Override
public boolean processPayment(double amount) {
System.out.println("Processing card payment of Rs. " + amount);
return true;
}
}
class UpiPayment implements PaymentMethod {
@Override
public boolean processPayment(double amount) {
System.out.println("Processing UPI payment of Rs. " + amount);
return true;
}
}
public class Main {
static void checkout(PaymentMethod method, double amount) {
boolean successful = method.processPayment(amount);
if (successful) {
System.out.println("Payment successful");
} else {
System.out.println("Payment failed");
}
}
public static void main(String[] args) {
PaymentMethod card = new CardPayment();
PaymentMethod upi = new UpiPayment();
checkout(card, 1500.00);
checkout(upi, 750.00);
}
}
Output
Processing card payment of Rs. 1500.0
Payment successful
Processing UPI payment of Rs. 750.0
Payment successful
How It Works
- The
PaymentMethod interface defines the processPayment() contract.
CardPayment and UpiPayment implement that contract differently.
- The
checkout() method accepts a PaymentMethod reference.
- The correct implementation runs according to the actual object passed to the method.
- A new payment implementation can be introduced without changing the general checkout logic, provided it follows the same contract.
Note: This is a learning example. Real payment systems require secure payment-provider integration, validation, transaction handling, and appropriate error management.
21. Common Errors and Troubleshooting
| Error |
Cause |
Solution |
| Class is not abstract and does not override abstract method |
A concrete class has missed an interface method. |
Implement every inherited abstract method or declare the class abstract. |
| Attempting to instantiate an interface |
Trying to use new directly with an interface. |
Create an object of a concrete implementing class. |
| Cannot reduce visibility of inherited method |
An implementation method is declared protected or package-private. |
Declare the implementation method public. |
| Method signature mismatch |
The method name, parameter types, or return type is incompatible. |
Match the interface declaration and use @Override. |
| Cannot assign a value to a final variable |
Trying to modify an interface constant. |
Use a different variable for changeable data. |
| Reference cannot access an implementation-specific method |
The method is not declared in the interface. |
Declare the required behavior in the interface or use an appropriate concrete type when necessary. |
| Conflicting default methods |
Two interfaces provide unrelated defaults with the same signature. |
Override the method and choose the required behavior. |
22. Best Practices for Using Interfaces
- Design interfaces around clear responsibilities and related behaviors.
- Use descriptive names such as
Readable, Comparable, or PaymentProcessor.
- Keep interface contracts small and focused when possible.
- Use
@Override when implementing or overriding methods.
- Program to interface types when implementation details are not needed.
- Use dependency injection to provide implementations where appropriate.
- Avoid exposing implementation-specific details unnecessarily.
- Use default methods thoughtfully to provide shared behavior without creating confusing contracts.
- Document method expectations, valid inputs, return values, and possible failures.
- Test implementations against the same interface contract.
23. Practice Exercises
Exercise 1: Shape Interface
Create a Shape interface with a calculateArea() method. Implement it in Circle and Rectangle classes. Print both areas.
Exercise 2: Employee Roles
Create a Workable interface containing a work() method. Implement it in Developer and Tester classes with different output messages.
Exercise 3: Multiple Interfaces
Create Printable and Shareable interfaces. Implement both in a Report class.
Exercise 4: Default Method
Create an interface with one abstract method and one default method. Implement the abstract method and call both methods.
Exercise 5: Notification System
Create a Notification interface with a send() method. Implement email and SMS notifications, then write a method that accepts a Notification reference.
24. Mini Project: Notification Management System
Objective: Build a small notification system that demonstrates interface implementation and runtime polymorphism.
Requirements
- Create a
Notification interface with a send(String message) method.
- Implement the interface in
EmailNotification, SmsNotification, and PushNotification classes.
- Create a service method that accepts a
Notification reference.
- Send the same message through different implementations.
- Test each implementation and verify that the service works without depending on a specific class.
Expected Learning Outcome
You will learn how interfaces separate contracts from implementation, how polymorphism supports interchangeable objects, and how new notification types can be added without rewriting the main service logic.
25. Interview Questions and Answers
Q1. What is an interface in Java?
Answer: An interface is a reference type that defines a contract for classes. It can declare abstract methods and can also contain default, static, and private methods.
Q2. Which keyword is used to implement an interface?
Answer: A class uses the implements keyword to implement an interface.
Q3. Can a class implement multiple interfaces?
Answer: Yes. A class can implement multiple interfaces by separating their names with commas.
Q4. Can we create an object of an interface?
Answer: No. An interface cannot be instantiated directly. However, an interface reference can point to an object of a concrete implementing class.
Q5. Are interface methods public by default?
Answer: Abstract methods declared in an interface are implicitly public. Default and static methods are also public unless they are declared private as permitted by Java's interface rules.
Q6. Are interface variables constants?
Answer: Yes. Fields declared in an interface are implicitly public static final.
Q7. Can an interface have a constructor?
Answer: No. Interfaces do not have constructors because they cannot be instantiated directly.
Q8. What is a default method?
Answer: A default method is an interface method with a body, introduced in Java 8. Implementing classes can inherit or override it.
Q9. What is the difference between a default method and a static method?
Answer: A default method is an instance method available through implementing objects. A static interface method belongs to the interface and is called using the interface name.
Q10. Can one interface extend another interface?
Answer: Yes. An interface can extend one or multiple interfaces using extends.
Q11. What happens if a class does not implement every abstract interface method?
Answer: The class must be declared abstract. Otherwise, the compiler reports an error.
Q12. Why are interfaces useful for polymorphism?
Answer: Different implementing classes can be accessed through the same interface reference, and the appropriate overridden method executes at runtime.
Q13. What is the difference between an interface and an abstract class?
Answer: An interface primarily defines a contract and supports implementation by multiple interfaces. An abstract class can also maintain instance state, define constructors, and share common implementation through class inheritance.
Q14. What is a functional interface?
Answer: A functional interface has exactly one abstract method. It can be implemented using a lambda expression or method reference. Default and static methods do not count toward the single abstract-method requirement.
Q15. What does the @Override annotation do?
Answer: It tells the compiler that a method is intended to override or implement an inherited method, helping detect signature mistakes.
26. Quick Revision Checklist
- An interface is declared using the
interface keyword.
- A class implements an interface using
implements.
- A concrete class must implement all inherited abstract methods.
- Interface abstract methods are implicitly public.
- Interface fields are implicitly
public static final.
- A class can implement multiple interfaces.
- An interface can extend multiple interfaces.
- Default methods provide instance behavior and may be overridden.
- Static interface methods are called using the interface name.
- Private interface methods support internal code reuse.
- Interface references support abstraction and runtime polymorphism.
- Use interfaces to create flexible, loosely coupled Java applications.
27. Conclusion
Interfaces are a fundamental Java feature for defining behavior contracts and building maintainable applications. They allow different classes to provide their own implementations while sharing a common type. By understanding interface declaration, implementation, multiple interfaces, inheritance, default methods, and polymorphism, developers can create flexible systems that are easier to extend and test.
Practice implementing interfaces in small Java programs before using them in larger applications. Focus on designing clear contracts and writing code that depends on abstractions instead of unnecessary implementation details.
Learn More with JustAcademy
Continue learning Java programming concepts through the Core Java Training Course.
Interested in learning more? Register for a Course Demo to explore the training options.
Visit the JustAcademy website for additional courses and learning resources.